package com.example.apidocserver.application.event.impl;

import com.example.apidocserver.application.dto.UserDocInfoDto;
import com.example.apidocserver.application.event.ApiEvent;
import com.example.apidocserver.domain.document.entity.ApiInfo;
import com.example.apidocserver.domain.document.entity.ApiParam;
import com.example.apidocserver.domain.document.entity.ApiParamHis;
import com.example.apidocserver.domain.document.event.ApiInfoDomainEvent;
import com.example.apidocserver.domain.document.event.FieldParamDomainEvent;
import com.example.apidocserver.domain.document.event.ParamHisDomainEvent;
import com.example.apidocserver.domain.user.entity.DocUsrHis;
import com.example.apidocserver.domain.user.event.UserDocInfoEventService;
import com.example.apidocserver.infrastructure.enums.HisIdEnum;
import com.example.apidocserver.infrastructure.util.result.ParamException;
import com.example.apidocserver.infrastructure.util.user.UserDocAuthUtil;
import com.example.apidocserver.interfaces.vo.ApiInfoAllVo;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;
import java.util.Objects;

/**
 * 接口相关处理事件
 *
 * @author xyqlg
 */
@Service
public class ApiEventImpl implements ApiEvent {
    @Resource
    private ParamHisDomainEvent paramHisDomainEvent;

    @Resource
    private FieldParamDomainEvent fieldParamDomainEvent;

    @Resource
    private ApiInfoDomainEvent apiInfoDomainEvent;

    @Resource
    private UserDocInfoEventService userDocInfoEventService;

    @Override
    public ApiInfoAllVo getApiInfo(Integer apiId, Integer envId, boolean writeFlag) {
        UserDocAuthUtil.currentDocInfo().setWriteFlag(writeFlag);
        DocUsrHis docUsrHis = userDocInfoEventService.getUsrLastInfo().setEnvId(envId);

        ApiInfoAllVo apiInfoAll = apiInfoDomainEvent.getApiInfoAll(apiId, docUsrHis);

        setUserHis(docUsrHis, apiInfoAll);

        return apiInfoAll;
    }

    private void setUserHis(DocUsrHis docUsrHis, ApiInfoAllVo apiInfoAll) {
        if (Objects.isNull(apiInfoAll)) {
            return;
        }
        boolean retFlag = true;
        if (Objects.nonNull(apiInfoAll.getApiInfo()) && Objects.nonNull(apiInfoAll.getApiInfo().getId())) {
            docUsrHis.setApiId(apiInfoAll.getApiInfo().getId());
            retFlag = false;
        }
        if (Objects.nonNull(apiInfoAll.getCurrentParamHis()) && Objects.nonNull(apiInfoAll.getCurrentParamHis().getId())) {
            docUsrHis.setHisId(apiInfoAll.getCurrentParamHis().getId());
            retFlag = false;
        }
        if (retFlag) {
            return;
        }
        userDocInfoEventService.setHisId(docUsrHis, HisIdEnum.API);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ApiInfoAllVo upsertParamHis(ApiParamHis apiParamHis, boolean addRltFlag) {
        // 1.查询接口信息
        ApiInfo apiInfo = apiInfoDomainEvent.queryById(apiParamHis.getApiId());
        if (Objects.isNull(apiInfo)) {
            throw new ParamException("接口已不存在。");
        }

        // 2.插入示例，根据示例生成参数说明对象、字段说明对象
        ApiInfoAllVo apiInfoAllVo = paramHisDomainEvent.upsertParamHis(apiParamHis, apiInfo);

        // 3.插入参数说明，并返回说明字段
        fieldParamDomainEvent.upsertParamDesc(apiInfoAllVo, addRltFlag);
        return apiInfoAllVo;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ApiParam upsertParamDesc(ApiParam paramDescVo) {
        return fieldParamDomainEvent.upsertParamDesc(paramDescVo);
    }

    @Override
    public ApiInfo upsertApiInfo(ApiInfo apiInfo) {
        return apiInfoDomainEvent.upsertApiInfo(apiInfo);
    }

    @Override
    public List<ApiInfo> findApiLike(ApiInfo apiInfo, Integer docId) {
        return apiInfoDomainEvent.findApiLike(apiInfo, docId);
    }

    @Override
    public List<ApiInfo> findAllBySpaceId(Integer spaceId) {
        return apiInfoDomainEvent.findAllBySpaceId(spaceId);
    }
}
